package exercise;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

// 线程安全版本的单例模式
class SingletonLazy{
    private static volatile SingletonLazy instance = null;
    private static Object lock = new Object();
    private SingletonLazy(){
        System.out.println("SingletonLazy");
    }
    public static SingletonLazy getInstance(){
        if(instance == null){
            synchronized(lock){
                if(instance == null){
                    instance = new SingletonLazy();        
                }           
            }            
        }
        return instance;    
    }                 
}

public class exercise006 {
    public static void main(String[] args) throws InterruptedException  {
        // demo01();
        // demo02();
        // SingletonLazy s1 = SingletonLazy.getInstance();
        
    }
    // 标准库实现阻塞队列
    public static void demo01() throws InterruptedException  {
        BlockingQueue<String> queue = new LinkedBlockingQueue<>(1000);
        //生产者
        Thread producer = new Thread(()->{
            int count = 1;
            while(true){
                try {
                    queue.put(""+count);
                    System.out.println("生产者生产了"+count);
                    count++;
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            
            }
        });
        //消费者
        Thread consumer = new Thread(()->{
            while(true){
                try {
                    String take = queue.take();
                    System.out.println("消费者消费了"+take);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } 
        });
        producer.start();
        consumer.start();
        producer.join();
        consumer.join();
    }

    // 基于数组模拟实现
    private static String[] queue = new String[1000];
    private static int head = 0;
    private static int tail = 0;
    private static int size = 0;
    private static Object lock = new Object();
    public static void demo02() throws InterruptedException {
        //生产者
        Thread producer = new Thread(()->{
            int count = 1;
            while(true){
                try {
                    put(""+count);
                    System.out.println("生产者生产了"+count);
                    count++;
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            
            }
        });
        //消费者
        Thread consumer = new Thread(()->{
            while(true){
                try {
                    String take = take();
                    System.out.println("消费者消费了"+take);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } 
        });
        producer.start();
        consumer.start();
        producer.join();
        consumer.join();
    }
    private static void put(String str) throws InterruptedException {
        synchronized (lock) {
            while(size == queue.length){
                lock.wait();
            }
            queue[tail] = str;
            tail++;
            if(tail == queue.length){
                tail = 0;
            }   
            size++;
            lock.notifyAll();
        }
    }
    private static String take() throws InterruptedException {
        synchronized (lock) {
            while(size == 0){
                lock.wait();
            }
            String str = queue[head];
            head++;
            if(head == queue.length){
                head = 0;
            }
            size--;
            lock.notifyAll();
            return str;
        }
    }
}



